package com.yingyi.org.service.impl;

import com.yingyi.basic.constant.Identity;
import com.yingyi.basic.exception.BusinessException;
import com.yingyi.basic.service.impl.BaseServiceImpl;
import com.yingyi.basic.util.Md5Utils;
import com.yingyi.basic.util.StrUtils;
import com.yingyi.org.domain.Employee;
import com.yingyi.org.mapper.EmployeeMapper;
import com.yingyi.org.service.IEmployeeService;
import com.yingyi.user.domain.Logininfo;
import com.yingyi.user.mapper.LogininfoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class EmployeeServiceImpl extends BaseServiceImpl<Employee> implements IEmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public List<Employee> getShopEmployees() {
        /**
         * 当id为null时查询所有的shopemployees
         * 当id非null时查询shop_id为id的shopemployee
         */
        return employeeMapper.queryByShopId(null);
    }

    @Override
    @Transactional
    public void insert(Employee employee) throws BusinessException {
        // 参数验证
        validateParameters(employee);

        /**
         * employee中盐值salt,password字段的处理
         */
        encryptPassword(employee);

        /**
         * 将Employee数据同步添加到t_logininfo表中
         * 1 先创建Logininfo对象，将数据存入t_logininfo表中
         * 2 将返回的自增增长主键存储Employee对象中
         * 3 将Employee对象存入t_employee表中
         */
        Logininfo logininfo =  employee2Logininfo(employee);

        logininfoMapper.insert(logininfo);

        employee.setLogininfo_id(logininfo.getId());

        employeeMapper.insert(employee);

        /**
         * 添加员工角色 表t_employee_role
         *  可以使用employee作为参数传递，其中包含employee_id字段和role_id字段
         *  也可以使用两个参数但需要配合@Param注解使用，给变量一个key名用于mybatis中取值
         */
        employeeMapper.insertEmployeeRole(employee);
    }


    @Override
    @Transactional
    public void update(Employee employee) throws BusinessException {
        // 参数验证
        validateParameters(employee);
        encryptPassword(employee);

        // 先更新t_logininfo中相应的记录
        Logininfo logininfo = employee2Logininfo(employee);
        logininfo.setId(employee.getLogininfo_id());

        logininfoMapper.update(logininfo);
        employeeMapper.update(employee);


        //更新中间表t_employee_role中记录
        employeeMapper.updateEmployeeRole(employee);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        Employee employee = employeeMapper.queryById(id);

        //先删除t_logininfo中相应的记录
        logininfoMapper.delete(employee.getLogininfo_id());

        //再删除t_employee表中的记录
        employeeMapper.delete(id);

        //删除中间表t_employee_role中的记录
        employeeMapper.deleteEmployeeRole(id);
    }

    @Override
    @Transactional
    public void patchDelete(List<Long> ids) {

        List<Employee> employees = new ArrayList<>();
        for (Long id : ids) {
            employees.add(employeeMapper.queryById(id));
        }
        if (employees == null || employees.isEmpty()) {
            return;
        }

        List<Long> logininfoIds = employees.stream().map(employee -> employee.getLogininfo_id()).collect(Collectors.toList());
        //先批量删除t_logininfo中的所有对应的记录
        logininfoMapper.patchDelete(logininfoIds);

        //再批量删除t_employee中记录
        employeeMapper.patchDelete(ids);
    }

    /**
     * 参数校验
     * @param employee
     */
    private void validateParameters(Employee employee) throws BusinessException {
        if(StringUtils.isEmpty(employee.getUsername())
            || StringUtils.isEmpty(employee.getPassword())
            || employee.getRole_id() == null){
            throw new BusinessException("参数为空!");
        }

        if(!StringUtils.isEmpty(employee.getConfirmPassword())&& !employee.getPassword().equals(employee.getConfirmPassword())){
            throw new BusinessException("密码不相同");
        }
    }


    /**
     * employee中salt字段和密码password的处理
     * @param employee
     */
    private void encryptPassword(Employee employee) {
        String password = employee.getPassword();
        Long id = employee.getId();

        String salt;
        if(employee.getSalt() == null || employee.getSalt().isEmpty()) {
            salt = StrUtils.getComplexRandomString(32);
            employee.setSalt(salt);
        } else {
            salt = employee.getSalt();
        }



        String pwdEncrypted = null;
        //如果employee中密码字段与数据库中的密码相同则表示不修改密码
        if(id == null){
            //添加数据需要增加密码
            pwdEncrypted = Md5Utils.encrypByMd5(salt.concat(password));
        } else {
            //修改employee记录
            Employee dbEmployee = employeeMapper.queryById(id);
            if (!dbEmployee.getPassword().equals(password)) {
                //前台有修改密码
                pwdEncrypted = Md5Utils.encrypByMd5(salt.concat(password));
            } else {
                pwdEncrypted = dbEmployee.getPassword();
            }
        }
        employee.setPassword(pwdEncrypted);
    }



    /**
     * 将Employee对象中的字段赋值给Logininfo中相应的字段
     * @param employee
     * @return
     */
    private Logininfo employee2Logininfo(Employee employee) {

        Logininfo logininfo = new Logininfo();
        /**
         * 相同属性的赋值
         */
        BeanUtils.copyProperties(employee, logininfo);

        /**
         * 不同属性
         * type disable 单独处理
         */
        logininfo.setType(Identity.EMPLOYEE);
        logininfo.setDisable(employee.getState() == 0);

        return logininfo;
    }

    /*


    @Override
    public Employee queryById(Long id) {
        return employeeMapper.queryById(id);
    }

    @Override
    public List<Employee> queryAll() {
        return employeeMapper.queryAll();
    }

    @Override
    @Transactional
    public void insert(Employee dept) {
        employeeMapper.insert(dept);
    }

    @Override
    @Transactional
    public void update(Employee dept) {
        employeeMapper.update(dept);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        employeeMapper.delete(id);
    }

    @Override
    public PageList<Employee> queryData(EmployeeQuery query) {
        //条件查询
        List<Employee> list = employeeMapper.queryData(query);

        //条件查询的结果总数
        Long count = employeeMapper.queryCount(query);

        return new PageList<Employee>(count, list);
    }

    @Override
    public void patchDelete(List<Long> ids) {
        employeeMapper.patchDelete(ids);
    }
*/

}
